home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / TinyGL / ami / content / ad709 / tinygl / src / zdither.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-08-15  |  3.7 KB  |  164 lines

  1. /*$T zdither.c GC 1.137 08/09/02 17:47:18 */
  2.  
  3. /*
  4.  * Highly optimised dithering 16 bits -> 8 bits. The formulas were taken in Mesa
  5.  * (Bob Mercier mercier@hollywood.cinenet.net).
  6.  */
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include "zbuffer.h"
  10. #include <assert.h>
  11.  
  12. #if defined(TGL_FEATURE_8_BITS)
  13.     #define _R                        5
  14.     #define _G                        9
  15.     #define _B                        5
  16.     #define _DX                        4
  17.     #define _DY                        4
  18.     #define _D                        (_DX * _DY)
  19.     #define _MIX(r, g, b)            (((g) << 6) | ((b) << 3) | (r))
  20.     #define DITHER_TABLE_SIZE        (1 << 15)
  21.     #define DITHER_INDEX(r, g, b)    ((b) + (g) * _B + (r) * (_B * _G))
  22.     #define MAXC                    256
  23. static int    kernel8[_DY * _DX] = {
  24.     0 * MAXC,
  25.     8 * MAXC,
  26.     2 * MAXC,
  27.     10 * MAXC,
  28.     12 * MAXC,
  29.     4 * MAXC,
  30.     14 * MAXC,
  31.     6 * MAXC,
  32.     3 * MAXC,
  33.     11 * MAXC,
  34.     1 * MAXC,
  35.     9 * MAXC,
  36.     15 * MAXC,
  37.     7 * MAXC,
  38.     13 * MAXC,
  39.     5 * MAXC,
  40. };
  41.  
  42. /* we build the color table and the lookup table */
  43. void ZB_initDither(ZBuffer *zb, int nb_colors, unsigned char *color_indexes, int *color_table) {
  44.     int c, r, g, b, i, index, r1, g1, b1;
  45.     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  46.  
  47.     if(nb_colors < (_R * _G * _B)) {
  48.         fprintf(stderr, "zdither: not enough colors\n");
  49.         exit(1);
  50.     }
  51.  
  52.     for(i = 0; i < nb_colors; i++) {
  53.         color_table[i] = 0;
  54.     }
  55.  
  56.     zb->nb_colors = nb_colors;
  57.     zb->ctable = malloc(nb_colors * sizeof(int));
  58.  
  59.     for(r = 0; r < _R; r++) {
  60.         for(g = 0; g < _G; g++) {
  61.             for(b = 0; b < _B; b++) {
  62.                 r1 = (r * 255) / (_R - 1);
  63.                 g1 = (g * 255) / (_G - 1);
  64.                 b1 = (b * 255) / (_B - 1);
  65.                 index = DITHER_INDEX(r, g, b);
  66.                 c = (r1 << 16) | (g1 << 8) | b1;
  67.                 zb->ctable[index] = c;
  68.                 color_table[index] = c;
  69.             }
  70.         }
  71.     }
  72.  
  73.     zb->dctable = malloc(DITHER_TABLE_SIZE);
  74.  
  75.     for(i = 0; i < DITHER_TABLE_SIZE; i++) {
  76.         r = (i >> 12) & 0x7;
  77.         g = (i >> 8) & 0xF;
  78.         b = (i >> 3) & 0x7;
  79.         index = DITHER_INDEX(r, g, b);
  80.         zb->dctable[i] = color_indexes[index];
  81.     }
  82. }
  83.  
  84. /* */
  85. void ZB_closeDither(ZBuffer *zb) {
  86.     free(zb->ctable);
  87.     free(zb->dctable);
  88. }
  89.  
  90.     #if 0
  91.  
  92. /* */
  93. int ZDither_lookupColor(int r, int g, int b) {
  94.     unsigned char    *ctable = zdither_color_table;
  95.     return ctable[_MIX(_DITH0(_R, r), _DITH0(_G, g), _DITH0(_B, b))];
  96. }
  97.     #endif
  98.     #define DITHER_PIXEL2(a) { \
  99.         register int    v, t, r, g, c; \
  100.         v = *(unsigned int *) (pp + (a)); \
  101.         g = (v & 0x07DF07DF) + g_d; \
  102.         r = (((v & 0xF800F800) >> 2) + r_d) & 0x70007000; \
  103.         t = r | g; \
  104.         c = ctable[t & 0xFFFF] | (ctable[t >> 16] << 8); \
  105.         *(unsigned short *) (dest + (a)) = c; \
  106.     }
  107.  
  108. /*
  109.  * NOTE: all the memory access are 16 bit aligned, so if buf or linesize are not
  110.  * multiple of 2, it cannot work efficiently (or hang!)
  111.  */
  112. void ZB_ditherFrameBuffer(ZBuffer *zb, unsigned char *buf, int linesize) {
  113.     int                        xk, yk, x, y, c1, c2;
  114.     unsigned char            *dest1;
  115.     unsigned short            *pp1;
  116.     int                        r_d, g_d, b_d;
  117.     unsigned char            *ctable = zb->dctable;
  118.     register unsigned char    *dest;
  119.     register unsigned short *pp;
  120.  
  121.     /* assert( ((long)buf & 1) == 0 && (linesize & 1) == 0); */
  122.     for(yk = 0; yk < 4; yk++) {
  123.         for(xk = 0; xk < 4; xk += 2)
  124.         {
  125.     #if BYTE_ORDER == BIG_ENDIAN
  126.             c1 = kernel8[yk * 4 + xk + 1];
  127.             c2 = kernel8[yk * 4 + xk];
  128.     #else
  129.             c1 = kernel8[yk * 4 + xk];
  130.             c2 = kernel8[yk * 4 + xk + 1];
  131.     #endif
  132.             r_d = ((c1 << 2) & 0xF800) >> 2;
  133.             g_d = (c1 >> 4) & 0x07C0;
  134.             b_d = (c1 >> 9) & 0x001F;
  135.  
  136.             r_d |= (((c2 << 2) & 0xF800) >> 2) << 16;
  137.             g_d |= ((c2 >> 4) & 0x07C0) << 16;
  138.             b_d |= ((c2 >> 9) & 0x001F) << 16;
  139.             g_d = b_d | g_d;
  140.  
  141.             dest1 = buf + (yk * linesize) + xk;
  142.             pp1 = zb->pbuf + (yk * zb->xsize) + xk;
  143.  
  144.             for(y = yk; y < zb->ysize; y += 4) {
  145.                 dest = dest1;
  146.                 pp = pp1;
  147.                 for(x = xk; x < zb->xsize; x += 16) {
  148.                     DITHER_PIXEL2(0);
  149.                     DITHER_PIXEL2(1 * 4);
  150.                     DITHER_PIXEL2(2 * 4);
  151.                     DITHER_PIXEL2(3 * 4);
  152.  
  153.                     pp += 16;
  154.                     dest += 16;
  155.                 }
  156.  
  157.                 dest1 += linesize * 4;
  158.                 pp1 += zb->xsize * 4;
  159.             }
  160.         }
  161.     }
  162. }
  163. #endif
  164.